-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat(db): add MDBX put-append for fast ordered puts #18603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some stlye nits, defer to @shekhirin on mdbx
} | ||
|
||
impl Tx<RW> { | ||
fn put<T: Table>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add some docs here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 🙏.
let key = key.encode(); | ||
let value = value.compress(); | ||
self.execute_with_operation_metric::<T, _>( | ||
Operation::Put, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how is putupsert different from just put?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's the same, just renamed for clarity. By default with flag 0
, put will do an upsert
reth/crates/storage/libmdbx-rs/mdbx-sys/libmdbx/mdbx.h
Lines 1624 to 1625 in cff5512
/** Upsertion by default (without any other flags) */ | |
MDBX_UPSERT = 0, |
/// Put upsert. | ||
PutUpsert, | ||
/// Put append. | ||
PutAppend, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add another enum for PutKind then this can replace the bool and we can do kind.into()
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Too many Into
s are annoying, so I did a simple TxKind::into_operation_and_flags
that covers everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this makes sense, nice catch that we can append not just for cursor, but for simple put
operations too.
Agreed with Matt's nits
a5f5641
to
af0185c
Compare
We only want 2 things in life:
This led us to
DatabaseProvider::insert_block
, which is still using put-upsert instead of put-append for tables with naturally increasing keys (likeBlockNumber
) in the happy/hot paths. For example:reth/crates/storage/provider/src/providers/database/provider.rs
Lines 2747 to 2755 in 4ddf3dd
This PR first adds
DbTxMut::append
with the optimised implementation for MDBX, and a benchmark to show how put-append is much faster than put-upsert in this scenario:Actual integration into key paths should be done in separate PRs with proper testing and benchmarks. Some places may be able to simply fall back to
put
, while others may want to report an error for different handling if the key is unexpectedly not the highest.